package com.milhouz.findmydroid.db;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;

import com.milhouz.findmydroid.bean.Character;
import com.milhouz.findmydroid.bean.Game;
import com.milhouz.findmydroid.exception.DatabaseRequestException;

public class AppDbAPI {

	private static final Random RANDOM = new Random();

	private static AppDbAPI instance;

	public static synchronized AppDbAPI getInstance() {
		if (instance == null) {
			instance = new AppDbAPI();
		}
		return instance;
	}

	public void insertCharacter(final Context context, final String name) {
		ContentValues values = new ContentValues();
		values.put(AppConstants.COLUMN_NAME, name);
		values.put(AppConstants.COLUMN_LANG, "all");
		values.put(AppConstants.COLUMN_IS_USER, "1");
		values.put(AppConstants.COLUMN_CATEGORY_ID, 0);
		context.getContentResolver().insert(AppProvider.CHARACTERS_URI, values);
	}

	public List<Character> getUserCharacters(final Context context) {
		List<Character> characters = new ArrayList<Character>();
		Cursor cursor = context.getContentResolver().query(AppProvider.CHARACTERS_URI, null, AppConstants.COLUMN_IS_USER + "=\"1\"", null, null);
		if (cursor != null && cursor.moveToFirst()) {
			do {
				try {
					characters.add(new Character(cursor));
				} catch (DatabaseRequestException e) {
					Log.e(AppConstants.TAG, "Error getting the character user", e);
				}
			} while (cursor.moveToNext());
			cursor.close();
		}
		return characters;
	}

	public void deleteCharacter(final Context context, final String name) {
		context.getContentResolver().delete(AppProvider.CHARACTERS_URI,
				AppConstants.COLUMN_NAME + "=\"" + name + "\" AND " + AppConstants.COLUMN_IS_USER + "=\"1\"", null);
	}

	public boolean isDataAlreadyLoaded(final Context context) {
		Cursor cursor = context.getContentResolver().query(ContentUris.withAppendedId(AppProvider.CHARACTERS_URI, 5), null, null, null, null);
		try {
			return cursor.moveToFirst();
		} finally {
			cursor.close();
		}
	}

	public void getRandomCharacters(final Context context, final Game game) {
		int totalCharacters = countCharacters(context);
		List<Integer> randomCharactersIds = new ArrayList<Integer>(game.getNbCards());
		int curId = 0;
		for (int i = 0; i < game.getNbCards(); i++) {
			curId = RANDOM.nextInt(totalCharacters) + 1;
			if (randomCharactersIds.contains(curId)) {
				i--;
			} else {
				try {
					game.getCharacters().add(getCharacterById(context, curId));
				} catch (DatabaseRequestException e) {
					Log.e(AppConstants.TAG, "Error getting the character " + curId, e);
				}
			}
		}
	}

	public int countCharacters(final Context context) {
		Cursor cursor = context.getContentResolver().query(AppProvider.CHARACTERS_URI, null, null, null, null);
		try {
			return cursor.getCount();
		} finally {
			cursor.close();
		}
	}

	public Character getCharacterById(final Context context, final int id) throws DatabaseRequestException {
		final Uri characterUri = ContentUris.withAppendedId(AppProvider.CHARACTERS_URI, id);
		Cursor cursor = context.getContentResolver().query(characterUri, null, null, null, null);
		if (cursor != null && cursor.moveToFirst()) {
			try {
				return new Character(cursor);
			} finally {
				cursor.close();
			}
		}
		return null;
	}

	public int getCategoryId(final Context context, String categoryName) {
		final Uri categoriesUri = Uri.withAppendedPath(AppProvider.CATEGORY_NAME_URI, categoryName);
		Cursor cursor = context.getContentResolver().query(categoriesUri, null, null, null, null);
		if (cursor != null && cursor.moveToFirst()) {
			int id = cursor.getInt(cursor.getColumnIndex(AppConstants.COLUMN_ID));
			cursor.close();
			return id;
		} else {
			return -1;
		}
	}

	public String getCategoryName(final Context context, int categoryId) {
		final Uri categoriesUri = ContentUris.withAppendedId(AppProvider.CATEGORIES_URI, categoryId);
		Cursor cursor = context.getContentResolver().query(categoriesUri, null, null, null, null);
		if (cursor != null && cursor.moveToFirst()) {
			String name = cursor.getString(cursor.getColumnIndex(AppConstants.COLUMN_NAME));
			cursor.close();
			return name;
		} else {
			return null;
		}
	}

	public String[] getCategories(final Context context) {
		Cursor cursor = context.getContentResolver().query(AppProvider.CATEGORY_NAME_URI, null, null, null, null);
		if (cursor != null && cursor.moveToFirst()) {
			int index = 0;
			String[] categories = new String[cursor.getCount()];
			do {
				categories[index] = cursor.getString(cursor.getColumnIndex(AppConstants.COLUMN_NAME));
				index++;
			} while (cursor.moveToNext());
			cursor.close();
			return categories;
		}
		return null;
	}
}
